#pragma once

#include "Common/Stream.h"
#include "Common/BinaryReader.h"

class Player;
struct GPlayerData
{
	UInt64		_uid;
	std::string	_nick;
	Int32		_score;
	
	GPlayerData() {}
	GPlayerData( UInt64 uid_, const std::string& nick_, Int32 score_ )
		: _uid(uid_), _nick(nick_), _score(score_)
	{}
};

struct GReportCell
{
	UInt32	_id;
	UInt32	_rid;
	UInt32	_time;
	GPlayerData * _gpds[4];

	GReportCell() 
	{
		memset( _gpds, 0x00, sizeof(_gpds) );
	}
	GReportCell(UInt32 rid_, UInt32 time_)
		: _rid(rid_), _time(time_)
	{
		memset( _gpds, 0x00, sizeof(_gpds) );
	}

	void appendData(Stream& st)
	{
		st << _id << _rid << _time;
		for (UInt8 i = 0; i < 4; ++i)
		{
			st << _gpds[i]->_uid << _gpds[i]->_nick;
			if (_gpds[i]->_score >= 0)
				st << static_cast<UInt8>(0) << _gpds[i]->_score;
			else
				st << static_cast<UInt8>(1) << static_cast<Int32>(-_gpds[i]->_score);
		}
	}

	void buildData(BinaryReader& br)
	{
		UInt32 id = 0;
		br >> id >> _rid >> _time;
		for (UInt8 i = 0; i < 4; ++i)
		{
			_gpds[i] = new GPlayerData();
			br >> _gpds[i]->_uid >> _gpds[i]->_nick;
			UInt8 sign = 0;
			Int32 score = 0;
			br >> sign >> score;
			_gpds[i]->_score = sign > 0 ? score : -score;
		}
	}

	std::vector<UInt64> getPids()
	{
		std::vector<UInt64> pids;
		for (UInt8 i = 0; i < 4; ++i)
			pids.push_back(_gpds[i]->_uid);
		return pids;
	}

	void save();
};

class GameReportManager
{
public:
	GameReportManager();
	~GameReportManager();

public:
	bool load();
	void update(UInt32);
	void add(GReportCell *);

	UInt8 getGameReport(UInt32, std::vector<UInt8>&);

	void appendReportListData(std::vector<UInt32>&, Stream&);

	std::multimap<UInt32, UInt32> getOnePlayerGameReport(UInt64);
	GReportCell * getGReport(UInt32);

protected:
	std::map<UInt32, GReportCell *> _cells;
};